<?php

use Phphub\Core\CreatorListener;
use Phphub\Forms\ReportCreationForm;
use Phphub\Exceptions\ManageReportsException;

class ReportsController extends \BaseController implements CreatorListener
{
    protected $report;

    public function __construct(Report $report)
    {
        parent::__construct();

        $this->beforeFilter('auth', ['except' => ['index', 'show']]);
        $this->report = $report;
    }

    public function authorOrAdminPermissioinRequire($author_id)
    {
        if (! Entrust::can('manage_reports') && $author_id != Auth::id()) {
            throw new ManageReportsException("permission-required");
        }
    }

    public function index()
    {
        $filter = $this->report->present()->getReportFilter();
        $reports = $this->report->getReportsWithFilter($filter);
        $nodes  = Node::allLevelUp();
        $links  = Link::remember(1440)->get();

        return View::make('reports.index', compact('reports', 'nodes', 'links'));
    }

    public function create()
    {
        $section = Section::find(Input::get('section_id'));

        $report = Report::where('section_id', $section->id)->first();
        if ($report) {
            return Redirect::route('reports.edit', $report->id);
        }

        $lab = $section->lab;
        $node = $lab->node;
        $nodes = Node::allLevelUp();

        return View::make('reports.create_edit', compact('nodes', 'node', 'section', 'lab'));
    }

    public function store()
    {
        return App::make('Phphub\Creators\ReportCreator')->create($this, Input::except('_token'));
    }

    public function show($id)
    {
        $report = Report::findOrFail($id);
        $report->increment('view_count', 1);
        $lab = $report->lab;
        $opinions = $report->getOpinionsWithLimit(Config::get('phphub.opinions_perpage'));

        $node = $report->node;
        $nodeReports = $report->getSameNodeReports();

        return View::make('reports.show', compact('report', 'nodeReports', 'node', 'opinions', 'lab'));
    }

    public function edit($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->user_id);
        $nodes = Node::allLevelUp();
        $section = Section::withTrashed()->find($report->section_id);
        $lab = $section->lab;
        $node = $lab->node;

        $report->body = $report->body_original;

        return View::make('reports.create_edit', compact('report', 'nodes', 'node', 'lab', 'section'));
    }

    public function append($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->user_id);

        $markdown = new Markdown;
        $content = $markdown->convertMarkdownToHtml(Input::get('content'));

        $append = Append::create(['report_id' => $report->id, 'content' => $content]);

        App::make('Phphub\Notification\Notifier')->newAppendNotify(Auth::user(), $report, $append);

        Flash::success(lang('Operation succeeded.'));
        return Redirect::route('reports.show', $report->id);
    }

    public function update($id)
    {
        $report = Report::findOrFail($id);
        $data = Input::only('title', 'body', 'section_id');

        $this->authorOrAdminPermissioinRequire($report->user_id);

        $markdown = new Markdown;
        $data['body_original'] = $data['body'];
        $data['body'] = $markdown->convertMarkdownToHtml($data['body']);

        // Validation
        App::make('Phphub\Forms\ReportCreationForm')->validate($data);

        $report->update($data);

        Flash::success(lang('Operation succeeded.'));
        return Redirect::route('reports.show', $report->id);
    }

    /**
     * ----------------------------------------
     * User Report Vote function
     * ----------------------------------------
     */

    public function vote($id)
    {
        $report = Report::find($id);
        App::make('Phphub\Vote\Voter')->reportUpVote($report);
        return Redirect::route('reports.show', $report->id);
    }

    /**
     * ----------------------------------------
     * Admin Report Management
     * ----------------------------------------
     */

    public function recomend($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->user_id);
        $report->is_excellent = (!$report->is_excellent);
        $report->save();
        Flash::success(lang('Operation succeeded.'));
        return Redirect::route('reports.show', $report->id);
    }

    public function rate($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->lab->user_id);
        $report->rate = intval(Input::get('rate'));
        $report->save();
        Flash::success(lang('Operation succeeded.'));
        return Redirect::route('reports.show', $report->id);
    }

    public function pin($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->user_id);
        ($report->order > 0) ? $report->decrement('order', 1) : $report->increment('order', 1);
        return Redirect::route('reports.show', $report->id);
    }

    public function sink($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->user_id);
        ($report->order >= 0) ? $report->decrement('order', 1) : $report->increment('order', 1);
        return Redirect::route('reports.show', $report->id);
    }

    public function destroy($id)
    {
        $report = Report::findOrFail($id);
        $this->authorOrAdminPermissioinRequire($report->user_id);
        $report->delete();
        Flash::success(lang('Operation succeeded.'));

        return Redirect::route('reports.index');
    }

    public function uploadImage()
    {
        if ($file = Input::file('file')) {
            $allowed_extensions = ["png", "jpg", "gif"];
            if ($file->getClientOriginalExtension() && !in_array($file->getClientOriginalExtension(), $allowed_extensions)) {
                return ['error' => 'You may only upload png, jpg or gif.'];
            }

            $fileName        = $file->getClientOriginalName();
            $extension       = $file->getClientOriginalExtension() ?: 'png';
            $folderName      = 'uploads/images/' . date("Ym", time()) .'/'.date("d", time()) .'/'. Auth::user()->id;
            $destinationPath = public_path() . '/' . $folderName;
            $safeName        = str_random(10).'.'.$extension;
            $file->move($destinationPath, $safeName);

            // If is not gif file, we will try to reduse the file size
            if ($file->getClientOriginalExtension() != 'gif') {
                // open an image file
                $img = Image::make($destinationPath . '/' . $safeName);
                // prevent possible upsizing
                $img->resize(1440, null, function ($constraint) {
                    $constraint->aspectRatio();
                    $constraint->upsize();
                });
                // finally we save the image as a new file
                $img->save();
            }

            $data['filename'] = getUserStaticDomain() . $folderName .'/'. $safeName;

            SiteStatus::newImage();
        } else {
            $data['error'] = 'Error while uploading file';
        }
        return $data;
    }

    /**
     * ----------------------------------------
     * CreatorListener Delegate
     * ----------------------------------------
     */

    public function creatorFailed($errors)
    {
        return Redirect::to('/');
    }

    public function creatorSucceed($report)
    {
        Flash::success(lang('Operation succeeded.'));

        return Redirect::route('reports.show', array($report->id));
    }
}
